<!-- ImageUpload.vue -->
<template>
	<view>
		<!-- 统一的上传入口，仅在未选择任何文件时显示 -->
		<view class="upload-trigger-wrapper">
			<view v-if="fileList.length === 0" class="upload" @click="openUploadActionSheet" :style="uploadStyle">
				<u-icon class="slot-icon" name="plus" color="#999999" :size="iconSize"></u-icon>
				<view style="font-size: 22rpx;">{{ uploadText }}</view>
			</view>
		</view>

		<!-- 图片上传与预览区域，仅当有图片文件时显示 -->
		<u-upload v-if="fileList.length > 0" :fileList="fileList" :maxCount="maxCount" :previewFullImage="true" name="1"
			ref="uUploadImage" multiple :width="width + 'rpx'" :height="height+ 'rpx'" @afterRead="handleImageUpload" @delete="deletePic">
		</u-upload>

		<!-- 上传选项弹窗 -->
		<u-action-sheet style="z-index: 99999;" :show="showUploadOptions" :actions="uploadActions" cancelText="取消"
			@select="handleUploadSelect" @close="showUploadOptions = false"></u-action-sheet>

		<!-- 全屏遮罩loading，阻止用户操作 -->
		<view v-if="isFullScreenLoading" class="fullscreen-loading">
			<view class="loading-content">
				<u-loading-icon size="40" color="#ffffff"></u-loading-icon>
				<text class="loading-text">{{ loadingText }}</text>
			</view>
		</view>
	</view>
</template>

<script>
	import config from '@/config/index.js'
	import {
		getQiniuToken
	} from '@/request/api.js'

	// 常量定义
	const POST_IMAGE_PURPOSE = 'post_image';

	// 上传操作配置（只保留图片相关）
	const UPLOAD_ACTIONS = [{
			name: '从相册选择照片',
			type: 'image',
			sourceType: ['album']
		},
		{
			name: '拍照',
			type: 'image',
			sourceType: ['camera']
		}
	];

	export default {
		name: 'ImageUpload',
		props: {
			// 上传类型：'post' 普通发布，'voucher' 凭证上传
			uploadType: {
				type: String,
				default: 'post'
			},
			// 最大文件数量
			maxCount: {
				type: Number,
				default: 10
			},
			// 上传按钮文字
			uploadText: {
				type: String,
				default: '上传图片'
			},
			// 初始文件列表
			initialFileList: {
				type: Array,
				default: () => []
			},
			// 宽度
			width: {
				type: [String, Number],
				default: 100
			},
			// 高度
			height: {
				type: [String, Number],
				default: 100
			},
			// 图标大小
			iconSize: {
				type: [String, Number],
				default: 20
			}
		},
		data() {
			return {
				// 上传相关
				showUploadOptions: false,
				uploadActions: UPLOAD_ACTIONS,
				fileList: [],
				isUploadingGlobally: false,
				// 全屏loading相关
				isFullScreenLoading: false,
				loadingText: '处理中...'
			}
		},
		computed: {
			// 计算当前是否正在上传
			isUploading() {
				return this.isUploadingGlobally ||
					this.fileList.some(item => item.status === 'uploading') ||
					this.isFullScreenLoading;
			},
			// 计算上传成功的文件列表
			successFiles() {
				return this.fileList.filter(item => item.status === 'success');
			},
			// 上传按钮样式
			uploadStyle() {
				return {
					width: this.formatSize(this.width),
					height: this.formatSize(this.height)
				};
			}
		},
		watch: {
			initialFileList: {
				handler(newVal) {
					this.fileList = [...newVal];
				},
				immediate: true
			}
		},
		methods: {
			// ==================== 工具方法 ====================
			// 格式化尺寸，支持数字和字符串
			formatSize(size) {
				if (typeof size === 'number') {
					return `${size}rpx`;
				}
				// 如果是字符串，检查是否包含单位，如果没有单位则添加px
				if (typeof size === 'string' && !isNaN(size) && size !== '') {
					return `${size}rpx`;
				}
				return size;
			},

			showToast(message, icon = 'none') {
				uni.showToast({
					title: message,
					icon,
					duration: 3000
				});
			},

			// 显示全屏loading
			showFullScreenLoading(text = '处理中...') {
				this.isFullScreenLoading = true;
				this.loadingText = text;
				// 禁用页面滚动
				uni.pageScrollTo({
					scrollTop: 0,
					duration: 0
				});
			},

			// 隐藏全屏loading
			hideFullScreenLoading() {
				this.isFullScreenLoading = false;
				this.loadingText = '处理中...';
			},

			// ==================== 上传相关方法 ====================
			openUploadActionSheet() {
				// 如果正在处理中，不允许打开上传选项
				if (this.isUploading) {
					this.showToast('正在处理中，请稍后...');
					return;
				}
				this.showUploadOptions = true;
			},

			handleUploadSelect(action) {
				const config = {
					image: {
						method: 'chooseImage',
						params: {
							count: this.maxCount - this.fileList.length,
							sourceType: action.sourceType,
							sizeType: ['compressed'],
						}
					}
				}[action.type];

				if (!config) return;

				uni[config.method]({
					...config.params,
					success: (res) => {
						const files = res.tempFiles.map(f => ({
							url: f.path,
							...f
						}));

						this.handleImageUpload({
							file: files
						});
					},
					fail: (err) => {
						console.error('选择文件失败:', err);
						this.showToast('选择文件失败');
					}
				});
			},

			// ==================== 图片上传方法（通过服务器接口）====================
			async uploadFileToQiniu(fileUrl, purpose) {
				return new Promise((resolve, reject) => {
					const base_url = config.baseURL
					uni.uploadFile({
						url: base_url + '/qnyUpload/upload',
						filePath: fileUrl,
						name: "file",
						header: {
							'Authorization': uni.getStorageSync('token') || '',
							'Accept': 'application/json'
						},
						success: (res) => {
							if (res.statusCode === 413) {
								reject(new Error('文件大小超过服务器限制，请选择较小的文件'));
								return;
							}
							try {
								const responseData = typeof res.data === 'string' ? JSON.parse(res
									.data) : res.data;
								if (responseData.code === 200) {
									const imageUrl = responseData.url;
									resolve(imageUrl);
								} else {
									reject(new Error(responseData.msg || '上传失败'));
								}
							} catch (error) {
								reject(new Error('服务器响应格式错误'));
							}
						},
						fail: (err) => {
							if (err.errMsg && err.errMsg.includes('request:fail')) {
								reject(new Error('网络连接失败，请检查网络设置'));
							} else {
								reject(new Error('网络请求失败'));
							}
						}
					});
				});
			},

			// 图片上传处理
			async handleImageUpload(event) {
				// 如果正在处理中，不允许重复上传
				if (this.isUploading) {
					this.showToast('正在处理中，请稍后...');
					return;
				}

				const lists = [].concat(event.file);
				if (lists.length === 0) return;

				await this.handleImageFilesUpload(lists);
			},

			async handleImageFilesUpload(lists) {
				this.showFullScreenLoading('图片上传中...');
				this.isUploadingGlobally = true;

				const newFilePlaceholders = lists.map(item => ({
					url: item.url,
					status: "uploading",
					message: "上传中...",
					originalName: item.name || `image_${Date.now()}.${item.url.split('.').pop() || 'jpg'}`,
					mimeType: item.type || 'image/jpeg',
					qiniuKey: null,
					_tempPath: item.url
				}));

				this.fileList.push(...newFilePlaceholders);

				try {
					await Promise.all(newFilePlaceholders.map(async (placeholder) => {
						const currentIndex = this.fileList.indexOf(placeholder);
						await this.uploadSingleImageFile(
							placeholder._tempPath,
							placeholder.originalName,
							currentIndex
						);
					}));
				} finally {
					this.isUploadingGlobally = false;
					this.hideFullScreenLoading();
				}
			},

			// 单张图片上传
			async uploadSingleImageFile(fileUrl, originalName, index) {
				try {
					const qiniuCdnUrl = await this.uploadFileToQiniu(fileUrl, POST_IMAGE_PURPOSE);
					const updatedFile = {
						...this.fileList[index],
						url: qiniuCdnUrl,
						status: 'success',
						message: '上传成功',
						qiniuKey: this.uploadKey
					};

					this.$set(this.fileList, index, updatedFile);
					this.$emit('upload-success', updatedFile);
				} catch (error) {
					this.fileList.splice(index, 1);
					this.showToast(error.message || `文件上传失败`);
					this.$emit('upload-error', error);
				}
			},

			// ==================== 删除方法 ====================
			deletePic(event) {
				// 如果正在处理中，不允许删除
				if (this.isUploading) {
					this.showToast('正在处理中，请稍后...');
					return;
				}
				const fileToDelete = this.fileList[event.index];
				if (fileToDelete.qiniuKey) {
					this.fileList.splice(event.index, 1);
				} else {
					this.fileList.splice(event.index, 1);
					this.showToast('图片已从列表移除');
				}
				this.$emit('file-deleted', fileToDelete);
			},

			// ==================== 公共方法 ====================
			// 获取上传成功的文件列表
			getSuccessFiles() {
				return {
					files: this.successFiles
				}
			},

			// 清空文件列表
			clearFiles() {
				// 如果正在处理中，不允许清空
				if (this.isUploading) {
					this.showToast('正在处理中，请稍后...');
					return;
				}
				this.fileList = [];
			},

			// 检查是否正在上传
			checkUploading() {
				return this.isUploading;
			}
		}
	}
</script>

<style lang="scss">
	/* 确保 ActionSheet 显示在最上层 */
	::v-deep .u-action-sheet {
		z-index: 10002 !important;
	}

	::v-deep .u-popup {
		z-index: 10002 !important;
	}

	.upload {
		background: #F8F8F8;
		color: #7C7B7B;
		display: flex;
		flex-direction: column;
		justify-content: center;
		align-items: center;
		font-size: 26rpx;
		border-radius: 20rpx;
		padding: 10rpx;
	}

	.upload-trigger-wrapper {
		// 布局样式
	}

	/* 全屏loading样式 */
	.fullscreen-loading {
		position: fixed;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		background-color: rgba(0, 0, 0, 0.7);
		display: flex;
		justify-content: center;
		align-items: center;
		z-index: 99999;
	}

	.loading-content {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		background-color: rgba(0, 0, 0, 0.8);
		padding: 40rpx;
		border-radius: 20rpx;
		min-width: 300rpx;
	}

	.loading-text {
		color: #ffffff;
		font-size: 28rpx;
		margin-top: 20rpx;
		text-align: center;
	}
</style>